package com.lipy.dubboconsumer.aop;

import com.lipy.dubboconsumer.tool.RedisUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Aspect
public class DemoAopFlow {
    /**
     * aop 流程
     * before -> around -> after -> afterreturn
     * 方法执行有异常：
     *   如果proceed方法捕获了异常，则不会调用afterthrow
     *   before -> around -> after -> afterreturn
     *   如果around中向外抛出异常，则会调用到afterthrow 并想外继续抛
     *   before -> around -> after -> afterthrow
     */
    @Resource
    RedisUtils redisUtils;

    @Pointcut("execution(public * com.lipy.dubboconsumer.service.AopFlowService.*(..))")
    public void AopFlowServiceAspect(){}

    @Before("AopFlowServiceAspect()")
    public void doBefore(){
        System.out.println("CacheAop.doBefore");
    }
    // before -> a

    @Around("AopFlowServiceAspect()")
    public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
        System.out.println("CacheAop.around");
//        MethodSignature methodSignature = (MethodSignature)joinpoint.getSignature();;
//        String[] parameterNames = methodSignature.getParameterNames();
//        Method method = methodSignature.getMethod();
//        Object[] args = joinpoint.getArgs();
//
//        MyCacheable myCacheable = method.getDeclaredAnnotation(MyCacheable.class);
//        String annoKey = myCacheable.key();
//
//        ExpressionParser parser = new SpelExpressionParser();
//        Expression expression = parser.parseExpression(annoKey);
//        EvaluationContext standardEvaluationContext = new StandardEvaluationContext();
//        String value = expression.getValue(standardEvaluationContext,String.class);
//        for (int i = 0; i < parameterNames.length; i++) {
//            standardEvaluationContext.setVariable(parameterNames[i],args[i]);
//        }
//        String cacheKey = expression.getValue(standardEvaluationContext).toString();
//
//        // key handle todo
//        // get value
//        Object o = redisUtils.get(cacheKey);
//        if(Objects.nonNull(o)){
//            return o;
//        }
//
//        Object proceed = joinpoint.proceed(); // 使用传入的参数执行
////        Object proceed = joinpoint.proceed(args); 使用自定义参数执行
//
//
//        return  proceed;

        return joinpoint.proceed();

    }
    @After("AopFlowServiceAspect()")
    public void after(JoinPoint joinpoint){
        System.out.println("CacheAop.after");
    }
    @AfterReturning("AopFlowServiceAspect()")
    public void AfterReturning(JoinPoint joinpoint){
        System.out.println("CacheAop.AfterReturning");
    }
    @AfterThrowing(pointcut = "AopFlowServiceAspect()",throwing = "e")
    public void AfterThrowing(JoinPoint joinpoint, Throwable e){
        System.out.println("CacheAop.AfterThrowing");
    }
}
